package JIndicators;

import com.dukascopy.api.IIndicators;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IIndicatorsProvider;
import com.dukascopy.api.indicators.IndicatorInfo;
import com.dukascopy.api.indicators.IndicatorResult;
import com.dukascopy.api.indicators.InputParameterInfo;
import com.dukascopy.api.indicators.IntegerRangeDescription;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;

public class temp implements IIndicator {
   
   private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private double[][] inputs = new double[6][];
    private int[] timePeriod = new int[1];
    private double[][] outputs = new double[7][];
    private IIndicator EMA_EURUSD;
    private IIndicator EMA_GBPUSD;
    private IIndicator EMA_USDJPY;
    private IIndicator EMA_USDCAD;
    private IIndicator EMA_USDCHF;
    private IIndicator EMA_USDSEK;
    
   @Override
   public void onStart(IIndicatorContext context) {
	  IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider();
      
	  indicatorInfo = new IndicatorInfo("DXY", "Shows US Dollar index", "My indicators",
              false, false, false, 6, 1, 7);
      
	  InputParameterInfo eurusd = new InputParameterInfo("EURUSD", InputParameterInfo.Type.DOUBLE);
      eurusd.setInstrument(Instrument.EURUSD);
      eurusd.setAppliedPrice(IIndicators.AppliedPrice.CLOSE);
      eurusd.setOfferSide(OfferSide.BID);
      
      EMA_EURUSD = indicatorsProvider.getIndicator("EMA");
      
      
      InputParameterInfo gbpusd = new InputParameterInfo("GBPUSD", InputParameterInfo.Type.DOUBLE);
      gbpusd.setInstrument(Instrument.GBPUSD);
      gbpusd.setAppliedPrice(IIndicators.AppliedPrice.CLOSE);
      gbpusd.setOfferSide(OfferSide.BID);
      
      InputParameterInfo gbpusdma = new InputParameterInfo("Instr1", InputParameterInfo.Type.DOUBLE){{
							      	setOfferSide(OfferSide.BID);
							    	setInstrument(Instrument.GBPUSD);
							       }};
							       
      InputParameterInfo eurusdma = new InputParameterInfo("Instr2", InputParameterInfo.Type.DOUBLE){{
							      	setOfferSide(OfferSide.BID);
							    	setInstrument(Instrument.EURUSD);
							       }};						       
      
      InputParameterInfo usdjpy = new InputParameterInfo("USDJPY", InputParameterInfo.Type.DOUBLE);
      usdjpy.setInstrument(Instrument.USDJPY);
      usdjpy.setAppliedPrice(IIndicators.AppliedPrice.CLOSE);
      usdjpy.setOfferSide(OfferSide.BID);
      
      InputParameterInfo usdcad = new InputParameterInfo("USDCAD", InputParameterInfo.Type.DOUBLE);
      usdcad.setInstrument(Instrument.USDCAD);
      usdcad.setAppliedPrice(IIndicators.AppliedPrice.CLOSE);
      usdcad.setOfferSide(OfferSide.BID);
      
      InputParameterInfo usdchf = new InputParameterInfo("USDCHF", InputParameterInfo.Type.DOUBLE);
      usdchf.setInstrument(Instrument.USDCHF);
      usdchf.setAppliedPrice(IIndicators.AppliedPrice.CLOSE);
      usdchf.setOfferSide(OfferSide.BID);
      
      InputParameterInfo usdsek = new InputParameterInfo("USDSEK", InputParameterInfo.Type.DOUBLE);
      usdsek.setInstrument(Instrument.USDSEK);
      usdsek.setAppliedPrice(IIndicators.AppliedPrice.CLOSE);
      usdsek.setOfferSide(OfferSide.BID);
      
        inputParameterInfos = new InputParameterInfo[] {   
                                               //usdsek,
        									gbpusdma,
        									eurusdma,
                                               gbpusd,
                                               usdjpy,
                                               usdcad,
                                               usdchf
                                                     };
        optInputParameterInfos = new OptInputParameterInfo[] {new OptInputParameterInfo("Time period EMA", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(5, 2, 1000, 1))};
        outputParameterInfos = new OutputParameterInfo[] 
                                       {new OutputParameterInfo("USD", OutputParameterInfo.Type.DOUBLE,OutputParameterInfo.DrawingStyle.LINE), 
                    	        		new OutputParameterInfo("SEK", OutputParameterInfo.Type.DOUBLE,OutputParameterInfo.DrawingStyle.LINE),
                    	        		new OutputParameterInfo("EUR", OutputParameterInfo.Type.DOUBLE,OutputParameterInfo.DrawingStyle.LINE),
                    	        		new OutputParameterInfo("GBP", OutputParameterInfo.Type.DOUBLE,OutputParameterInfo.DrawingStyle.LINE),
                    	        		new OutputParameterInfo("JPY", OutputParameterInfo.Type.DOUBLE,OutputParameterInfo.DrawingStyle.LINE),
                    	        		new OutputParameterInfo("CAD", OutputParameterInfo.Type.DOUBLE,OutputParameterInfo.DrawingStyle.LINE),
                    	        		new OutputParameterInfo("CHF", OutputParameterInfo.Type.DOUBLE,OutputParameterInfo.DrawingStyle.LINE)};

   }

   @Override
   public IndicatorInfo getIndicatorInfo() {
      return indicatorInfo;
   }

   @Override
   public InputParameterInfo getInputParameterInfo(int index) {
      if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
      return null;
   }

   @Override
   public OptInputParameterInfo getOptInputParameterInfo(int index) {
      // TODO Auto-generated method stub
	   if (index <= optInputParameterInfos.length) {
           return optInputParameterInfos[index];
       }
       return null;
   }

   @Override
   public OutputParameterInfo getOutputParameterInfo(int index) {
      if (index <= outputParameterInfos.length) {
            return outputParameterInfos[index];
        }
      return null;
   }

   @Override
   public void setInputParameter(int index, Object array) {
      inputs[index] = (double[]) array;
   }

   @Override
   public void setOptInputParameter(int index, Object value) {
      // TODO Auto-generated method stub

   }

   @Override
   public void setOutputParameter(int index, Object array) {
      outputs[index] = (double[]) array;
   }

   @Override
   public int getLookback() {
      return timePeriod[0];
   }

   @Override
   public int getLookforward() {
      return 0;
   }

   @Override
   public IndicatorResult calculate(int startIndex, int endIndex) {
      //calculating startIndex taking into account lookback value
        /*if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }*/
        
        if (startIndex > endIndex) {
           return new IndicatorResult(0, 0);
        }
        
        /*EMA_GBPUSD.setInputParameter(0, inputs[0]);
        EMA_GBPUSD.setOptInputParameter(0, timePeriod);
        EMA_GBPUSD.setOutputParameter(0, outputs[0]);
        EMA_GBPUSD.calculate(startIndex, endIndex);*/
        
        double [] emaOutput1 = new double[endIndex];
        EMA_GBPUSD.setInputParameter(0, inputs[0]);
        EMA_GBPUSD.setOptInputParameter(0, timePeriod[0]);
        EMA_GBPUSD.setOutputParameter(0, emaOutput1);
        IndicatorResult ema1 = EMA_GBPUSD.calculate(startIndex, endIndex);
        
        double [] emaOutput2 = new double[endIndex];
        EMA_EURUSD.setInputParameter(0, inputs[1]);
        EMA_EURUSD.setOptInputParameter(0, timePeriod[0]);
        EMA_EURUSD.setOutputParameter(0, emaOutput1);
        IndicatorResult ema2 = EMA_EURUSD.calculate(startIndex, endIndex);
        
        int  j;
        /*double dxy = 1;
        double[] eurusd = new double[endIndex+1];
        double[] gbpusd = new double[endIndex+1];
        double[] usdjpy = new double[endIndex+1];
        double[] usdcad = new double[endIndex+1];
        double[] usdchf = new double[endIndex+1];
        double[] usdsek = new double[endIndex+1];
      
      
      dxyArrayCopy(endIndex, inputs[0], usdsek);
      dxyArrayCopy(endIndex, inputs[1], eurusd);
      dxyArrayCopy(endIndex, inputs[2], gbpusd);
      dxyArrayCopy(endIndex, inputs[3], usdjpy);
      dxyArrayCopy(endIndex, inputs[4], usdcad);
      dxyArrayCopy(endIndex, inputs[5], usdchf);*/
      
      
        for (j = startIndex; j <= endIndex; j++) {

             // US Dollar Index = 50.14348112 × EUROUS Dollar^(-0.576) × US Dollar JP Yen^(0.136) × 
             // GBPUS Dollar^(-0.119) × US Dollar CAD^(0.091) × US Dollar SEK^(0.042) × US Dollar CHF^(0.036)
             //dxy = (eurusd[j] + gbpusd[j])/2; 
            	 
            outputs[0][j] = emaOutput1[j] - emaOutput2[j];
            //outputs[1][j] = (eurusd[j] + gbpusd[j])/2 - 1;
        }
        return new IndicatorResult(startIndex, j);
   }
   
   public static double[] dxyArrayCopy(int endIndex, double[] src, double[] dst){
      if( (endIndex+1) <= src.length) {
         System.arraycopy(src, src.length - (endIndex+1), dst, 0, endIndex+1);
      }else{
         System.arraycopy(src, 0, dst, (endIndex+1) - src.length, src.length);
      }
      return dst;
   }
}